/******************************************/
/*	practica de desarrollo de sistemas	  */
/******************************************/

/******************************************/
/*										  */
/*	   Interprete sencillo de comandos    */
/*										  */
/******************************************/
 
 
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

#define TAM 255
#define SALIR "exit"

int main(int argc, char **argv)
{
	char *path;	//Almacenaremos la variable $PATH
	char *directorios[TAM]; //Almacenaremos los directorios de la variable $path
	char comando[TAM]; //Para almacenar los comandos introducidos por el usuario.
	char rutaCompleta[TAM];
	char *tokens[20], *commnd;	//Almacenara los argumentos del programa y el comando.
	int tokCont;	//Contador de tokens
	pid_t pid1;	//Se usan para crear los clones del proceso.
	short exit = 0;
	int dirCont=0; //contador de directorios del path
	int c;	//utilizado para algunos bucles.
	
	path = getenv("PATH");
	
	directorios[dirCont] = strtok(path, ":");
	while( (directorios[dirCont] = strtok(NULL, ":")) != NULL)
	{
				dirCont++; //Si quedans tokens, incrementa el contador en 1
	}

	
	for(c=0; c<dirCont;c++)
	{
		strcat(directorios[c], "/");	//Añádimos al final de cada path una barra para la correcta ejecucion de los comandos.
	}
	while(exit != 1)	//Bucle infinito o hasta que exit valga 1, que captura los comandos
	{
		printf("}");
		scanf("%[^\n]", comando);
		fflush(stdin);
		
		if((strcmp(comando, "exit") != 0))	//Si comando es igual a salir, salimos de la ejecucion
		{
			tokens[0] = strtok(comando, " ");
			tokCont = 1;
			while( (tokens[tokCont] = strtok(NULL, " ")) != NULL)
			{
				tokCont++; //Si quedans tokens, incrementa el contador en 1
			}
			
			pid1 = fork();
			if(pid1==0)	//Segmento de codigo que ejecutara el proceso padre
			{
				if(tokCont == 1)
				{
					printf("\n");
					for(c=0; c<dirCont;c++)
					{
						strcpy(rutaCompleta, directorios[c]);
						strcat(rutaCompleta, tokens[0]);
						execl(rutaCompleta, NULL); //el momento que tenga exito, el programa hijo cerrara, si llega fuera del bucle, hubo error ejecutando el programa.
					}
					printf("\nError ejecutando el comando\n");
					return -1;
				}
				else if(tokCont >1)
				{
					printf("\n");
					for(c=0; c<dirCont;c++)
					{
						strcpy(rutaCompleta, directorios[c]);
						strcat(rutaCompleta, tokens[0]);
						execv(rutaCompleta, tokens); //el momento que tenga exito, el programa hijo cerrara, si llega fuera del bucle, hubo error ejecutando el programa.
					}
					printf("\nError ejecutando el comando\n");
					return -1;
				}
				return 0;
			}
			else if(pid1<0)	//Segmento de codigo que ejecutara el proceso hijo
			{
				printf("Error ejecutando el comando\n");
				return 0;
			}
		}
		else
			exit = 1;
		strcpy(rutaCompleta, " ");
		getchar();
	}
	return 0;
}
